/**
 * 日志工具类
 * 提供统一的日志记录功能，便于问题排查和系统监控
 */

export interface LogContext {
  userId?: number;
  orderId?: string;
  platOrderNum?: string;
  action?: string;
  [key: string]: any;
}

export class Logger {
  private static formatMessage(level: string, message: string, context?: LogContext): string {
    const timestamp = new Date().toISOString();
    const contextStr = context ? ` | Context: ${this.safeStringify(context)}` : '';
    return `[${timestamp}] [${level}] ${message}${contextStr}`;
  }

  private static safeStringify(context: LogContext): string {
    try {
      return JSON.stringify(context, (_, value) => (typeof value === 'bigint' ? value.toString() : value));
    } catch (error) {
      const message = error instanceof Error ? error.message : String(error);
      return `Unserializable context: ${message}`;
    }
  }

  static info(message: string, context?: LogContext): void {
    console.log(this.formatMessage('INFO', message, context));
  }

  static warn(message: string, context?: LogContext): void {
    console.warn(this.formatMessage('WARN', message, context));
  }

  static error(message: string, error?: Error | unknown, context?: LogContext): void {
    const errorInfo = error instanceof Error ? {
      name: error.name,
      message: error.message,
      stack: error.stack
    } : error;
    
    const fullContext = { ...context, error: errorInfo };
    console.error(this.formatMessage('ERROR', message, fullContext));
  }

  static debug(message: string, context?: LogContext): void {
    if (process.env.NODE_ENV === 'development') {
      console.debug(this.formatMessage('DEBUG', message, context));
    }
  }

  // TopPay 专用日志方法
  static topPayRequest(action: string, data: any, context?: LogContext): void {
    this.info(`TopPay请求: ${action}`, {
      ...context,
      action,
      requestData: data
    });
  }

  static topPayResponse(action: string, response: any, context?: LogContext): void {
    this.info(`TopPay响应: ${action}`, {
      ...context,
      action,
      responseData: response
    });
  }

  static topPayError(action: string, error: Error | unknown, context?: LogContext): void {
    this.error(`TopPay错误: ${action}`, error, {
      ...context,
      action
    });
  }

  // 订单相关日志
  static orderCreated(orderId: string, context?: LogContext): void {
    this.info('订单创建成功', {
      ...context,
      orderId,
      action: 'ORDER_CREATED'
    });
  }

  static orderStatusChanged(orderId: string, oldStatus: string, newStatus: string, context?: LogContext): void {
    this.info('订单状态变更', {
      ...context,
      orderId,
      oldStatus,
      newStatus,
      action: 'ORDER_STATUS_CHANGED'
    });
  }

  static notificationReceived(orderId: string, notification: any, context?: LogContext): void {
    this.info('收到异步通知', {
      ...context,
      orderId,
      notification,
      action: 'NOTIFICATION_RECEIVED'
    });
  }
}

/**
 * 错误类型定义
 */
export enum ErrorCode {
  // 通用错误
  INTERNAL_ERROR = 'INTERNAL_ERROR',
  VALIDATION_ERROR = 'VALIDATION_ERROR',
  PERMISSION_DENIED = 'PERMISSION_DENIED',

  // 支付相关错误
  PAYMENT_CONFIG_ERROR = 'PAYMENT_CONFIG_ERROR',
  PAYMENT_API_ERROR = 'PAYMENT_API_ERROR',
  PAYMENT_SIGN_ERROR = 'PAYMENT_SIGN_ERROR',
  PAYMENT_CHANNEL_ERROR = 'PAYMENT_CHANNEL_ERROR',

  // TopPay相关错误
  TOPPAY_CONFIG_ERROR = 'TOPPAY_CONFIG_ERROR',
  TOPPAY_API_ERROR = 'TOPPAY_API_ERROR',
  TOPPAY_SIGNATURE_ERROR = 'TOPPAY_SIGNATURE_ERROR',

  // 订单相关错误
  ORDER_NOT_FOUND = 'ORDER_NOT_FOUND',
  ORDER_STATUS_ERROR = 'ORDER_STATUS_ERROR',
  DUPLICATE_ORDER = 'DUPLICATE_ORDER',
  INVALID_ORDER_STATUS = 'INVALID_ORDER_STATUS',

  // 用户相关错误
  USER_NOT_FOUND = 'USER_NOT_FOUND',

  // 支付订单相关错误
  PAYOUT_CREATE_ERROR = 'PAYOUT_CREATE_ERROR',
  PAYOUT_QUERY_ERROR = 'PAYOUT_QUERY_ERROR',
  PAYOUT_GET_ERROR = 'PAYOUT_GET_ERROR',
  PAYOUT_PASSWORD_NOT_SET = 'PAYOUT_PASSWORD_NOT_SET',
  INVALID_PAYOUT_PASSWORD = 'INVALID_PAYOUT_PASSWORD',
  INVALID_CURRENT_PASSWORD = 'INVALID_CURRENT_PASSWORD',
  
  // 支付通知相关错误
  PAYMENT_NOTIFICATION_INVALID = 'PAYMENT_NOTIFICATION_INVALID',
  PAYMENT_NOTIFICATION_PARSE_ERROR = 'PAYMENT_NOTIFICATION_PARSE_ERROR',
}

/**
 * 自定义错误类
 */
export class AppError extends Error {
  public readonly code: ErrorCode;
  public readonly context?: LogContext;

  constructor(message: string, code: ErrorCode = ErrorCode.INTERNAL_ERROR, context?: LogContext) {
    super(message);
    this.name = 'AppError';
    this.code = code;
    this.context = context;

    // 记录错误日志
    Logger.error(`应用错误: ${code}`, this, context);
  }
}

/**
 * TopPay专用错误类
 */
export class TopPayError extends AppError {
  constructor(message: string, context?: LogContext) {
    super(message, ErrorCode.TOPPAY_API_ERROR, context);
    this.name = 'TopPayError';
  }
}

/**
 * 错误处理工具函数
 */
export function handleError(error: unknown, defaultMessage: string = '操作失败'): AppError {
  if (error instanceof AppError) {
    return error;
  }

  if (error instanceof Error) {
    Logger.error('未处理的错误', error);
    return new AppError(error.message || defaultMessage, ErrorCode.INTERNAL_ERROR);
  }

  Logger.error('未知错误', error);
  return new AppError(defaultMessage, ErrorCode.INTERNAL_ERROR);
}

/**
 * 异步操作错误处理装饰器
 */
export function withErrorHandling<T extends any[], R>(
  fn: (...args: T) => Promise<R>,
  context?: LogContext
): (...args: T) => Promise<R> {
  return async (...args: T): Promise<R> => {
    try {
      return await fn(...args);
    } catch (error) {
      Logger.error('异步操作失败', error, context);
      throw handleError(error);
    }
  };
}
